/**
 * Copyright (C), 2015-2018, XXX有限公司
 * FileName: UserMgrController
 * Author:   zhouheng
 * Date:     2018/7/2 22:06
 * Description: 用户管理类
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.hengby.hengcrud.modular.sys.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.hengby.hengcrud.core.common.Const;
import com.hengby.hengcrud.core.common.annotation.BussinessLog;
import com.hengby.hengcrud.core.common.annotation.Permission;
import com.hengby.hengcrud.core.common.dictmap.UserDict;
import com.hengby.hengcrud.core.common.factory.ConstantFactory;
import com.hengby.hengcrud.core.common.status.ManagerStatus;
import com.hengby.hengcrud.core.exception.HengCrudException;
import com.hengby.hengcrud.core.exception.HengCrudExceptionEnum;
import com.hengby.hengcrud.core.log.LogObjectHolder;
import com.hengby.hengcrud.core.shiro.ShiroKit;
import com.hengby.hengcrud.core.shiro.ShiroUser;
import com.hengby.hengcrud.core.util.FileUtil;
import com.hengby.hengcrud.core.util.ToolUtil;
import com.hengby.hengcrud.modular.base.controller.BaseController;
import com.hengby.hengcrud.modular.base.tips.Tips;
import com.hengby.hengcrud.modular.sys.factory.UserFactory;
import com.hengby.hengcrud.modular.sys.model.User;
import com.hengby.hengcrud.modular.sys.service.IUserService;
import com.hengby.hengcrud.modular.sys.transfer.UserDto;
import com.hengby.hengcrud.modular.sys.warpper.UserWarpper;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 〈一句话功能简述〉<br> 
 * 〈用户管理类〉
 *
 * @author zhouheng
 * @create 2018/7/2
 * @since 1.0.0
 */
@Controller
@RequestMapping("/mgr")
@Slf4j
@Api(tags="用户控制类")
public class UserMgrController extends BaseController{

    @Autowired
    IUserService userService;


    private static String PREFIX = "/system/user/";

    @RequestMapping(path = {"/",""})
    public String index() {
        return "test";
    }

    @RequestMapping("/user")
    public String list() {
        return PREFIX + "user_list";
    }

    /**
     * @description: 用户新增
     * @date: 2018/7/10 17:44
     * @author:zhouheng
     */
    @RequestMapping("/user/user_add")
    public String addUser() {
        return PREFIX+"user_add";
    }

    @ResponseBody
    @RequestMapping(value = "/testApi")
    @ApiOperation(value = "测试swagger2",httpMethod = "GET")
    public String testApi(){
        return "hello swagger2";
    }

    /**
     * 添加用户
     */
    @RequestMapping("/user/add")
    @BussinessLog(value = "新增用户", key = "sex", dict= UserDict.class)
    @Permission(value = Const.ADMIN_NAME)
    @ResponseBody
    @ApiOperation(value = "新增用户信息")
    public Tips add(@Valid UserDto userDto, BindingResult result){
        if (result.hasErrors()){
            throw new HengCrudException(HengCrudExceptionEnum.REQUEST_NULL);
        }
        // 判断账号是否重复
        User user = userService.getByAccount(userDto.getAccount());
        if (user != null){
            throw new HengCrudException(HengCrudExceptionEnum.USER_ALREADY_REG);
        }else {
            // 完善账号信息
            userDto.setSalt(ShiroKit.getRandomSalt(4));
            userDto.setPassword(ShiroKit.md5(userDto.getPassword(), userDto.getSalt()));
            userDto.setStatus(ManagerStatus.OK.getCode());
            userDto.setCreatetime(new Date());

            this.userService.insert(UserFactory.createUser(userDto));

            return SUCCESS_TIP;
        }
    }

    /**
     * 修改用户
     */
    @RequestMapping("/user/edit")
    @BussinessLog(value = "修改用户", key = "account", dict= UserDict.class)
    @ResponseBody
    @ApiOperation(value = "修改用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",value = "用户id",required = true,
                    paramType="form",dataType = "Integer",defaultValue = ""),
            @ApiImplicitParam(name = "account",value = "用户账户",required = true,
                    paramType="form",dataType = "String",defaultValue = ""),
            @ApiImplicitParam(name = "password",value = "用户密码",required = true,
                    paramType="form",dataType = "String",defaultValue = "")
    })
    @ApiResponses({
            @ApiResponse(code=500,message="请求参数没填好，请求异常"),
            @ApiResponse(code=404,message="请求路径没有或页面跳转路径不对")
    })
    public Tips edit(@Valid UserDto userDto, BindingResult result){
        if (result.hasErrors()){
            throw new HengCrudException(HengCrudExceptionEnum.REQUEST_NULL);
        }
        ShiroUser shiroUser = ShiroKit.getUser();
        if (shiroUser.getId().equals(userDto.getId())) {
            this.userService.updateById(UserFactory.createUser(userDto));

            return SUCCESS_TIP;
        } else {
            throw new HengCrudException(HengCrudExceptionEnum.NO_PERMITION);
        }
    }

    @RequestMapping("/user/excel")
    @ResponseBody
    @ApiOperation(value = "导出excel",httpMethod="POST")
    public Tips dictExcel() {
        try {
            List<User> list = this.userService.selectList(new EntityWrapper<>());
            return FileUtil.createExcelByPOIKit("用户表", list, User.class);
        } catch (Exception e) {
            e.printStackTrace();
            throw new HengCrudException(HengCrudExceptionEnum.EXPORT_EXCEL_ERROR);
        }
    }

    /**
     * 修改用户
     */
    @RequestMapping("/user/delete/{userId}")
    @ResponseBody
    @ApiOperation(value = "删除用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",value = "用户id",required = true,
                    paramType="form",dataType = "Integer",defaultValue = ""
            )
    })
    @ApiResponses({
            @ApiResponse(code=500,message="服务器异常")
    })
    public Tips delete(@PathVariable("userId") Integer userId){
        ShiroUser shiroUser = ShiroKit.getUser();
        if (shiroUser == null){
            throw new HengCrudException(HengCrudExceptionEnum.NO_PERMITION);
        }
        if (ToolUtil.isEmpty(userId)){
            throw new HengCrudException(HengCrudExceptionEnum.REQUEST_NULL);
        }
        //不能删除超级管理员
        if (userId.equals(Const.ADMIN_ID)) {
            throw new HengCrudException(HengCrudExceptionEnum.CANT_DELETE_ADMIN);
        }

        this.userService.setStatus(userId, ManagerStatus.DELETED.getCode());

        return SUCCESS_TIP;

    }

    /**
     * 重置管理员的密码
     */
    @RequestMapping("/reset")
//    @BussinessLog(value = "重置管理员密码", key = "userId", dict = UserDict.class)
    @Permission(com.hengby.hengcrud.core.constants.Const.ADMIN_NAME)
    @ResponseBody
    public Tips reset(@RequestParam Integer userId) {
        if (ToolUtil.isEmpty(userId)) {
            throw new HengCrudException(HengCrudExceptionEnum.REQUEST_NULL);
        }
        assertAuth(userId);
        User user = this.userService.selectById(userId);
        user.setSalt(ShiroKit.getRandomSalt(5));
        user.setPassword(ShiroKit.md5(Const.DEFAULT_PWD, user.getSalt()));
        this.userService.updateById(user);
        return SUCCESS_TIP;
    }

    @RequestMapping(value = "/user/list")
    @ResponseBody
    public Object list(@RequestParam(required = false) String name,
                       @RequestParam(required = false) String beginTime,
                       @RequestParam(required = false) String endTime,
                       @RequestParam(required = false) Integer deptid) {
        if (ShiroKit.isAdmin()) {
            List<Map<String, Object>> users = userService.selectUsers(null, name, beginTime, endTime, deptid);
            return new UserWarpper(users).wrap();
        } else {
//            DataScope dataScope = new DataScope(ShiroKit.getDeptDataScope());
//            List<Map<String, Object>> users = userService.selectUsers(dataScope, name, beginTime, endTime, deptid);
//            return new UserWarpper(users).warp();
        }

        return null;
    }

    @RequestMapping(value = "user/user_edit/{selItem}")
    public String userEdit(@PathVariable(value = "selItem") Integer selItem,Model model) {
        if (ToolUtil.isEmpty(selItem)){
            throw new HengCrudException(HengCrudExceptionEnum.REQUEST_NULL);
        }

        // 根据所选行，获取用户对象信息
        User user = userService.selectById(selItem);
        // 保存到临时存储地
        LogObjectHolder.me().set(user);

        // 获取部门名称
        String deptName = ConstantFactory.me().getDeptName(user.getDeptid());
        // 获取角色名称
        String roleName = ConstantFactory.me().getRoleName(user.getRoleid());

//        UserDto userDto = new UserDto();
//        BeanUtils.copyProperties(user,userDto);
        model.addAttribute("user", user);
        model.addAttribute("roleName", roleName);
        model.addAttribute("deptName", deptName);

        return PREFIX+"user_edit";
    }

    /**
     * 判断当前登录的用户是否有操作这个用户的权限
     */
    private void assertAuth(Integer userId) {
        if (ShiroKit.isAdmin()) {
            return;
        }
        List<Integer> deptDataScope = ShiroKit.getDeptDataScope();
        User user = this.userService.selectById(userId);
        Integer deptid = user.getDeptid();
        if (deptDataScope.contains(deptid)) {
            return;
        } else {
            throw new HengCrudException(HengCrudExceptionEnum.NO_PERMITION);
        }
    }

}